package rsa;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;

import java.util.HashMap;
import java.util.Map;

/**
 * @author luoxiaohui
 * @Description: TODO(用一句话描述该文件做什么)
 * @date 2016年8月17日 上午9:56:08
 */

public class RSATest {

  /***
   * 公钥指数是随意选的，但目前行业上公钥指数普遍选的都是65537（0x10001，5bits），该值是除了1、3、5、17、257之外的最小素数，
   * 为什么不选的大一点？当然可以，只是考虑到既要满足相对安全、又想运算的快一点（加密时），PKCS#1的一个建议值而已
   * 有意的把公钥指数选的小一点，但是对应私钥指数肯定很大，意图也很明确，大家都要用公钥加密，所以大家时间很宝贵，
   * 需要快一点，您一个人私钥解密，时间长一点就多担待，少数服从多数的典型应用
   */
  private static String publicexponent = "010001";
  private static String publicModulus = "00aaddf90bdd1f2aedb8a16794757ad8ff7fc477d5da9b65c1e85d3a9d41b6dfa3f8e4bbf6a4b190cdc80ed96ef2d8ab84fa8b00ff6931d744b3514d7061cf009962dacd920ae927de9c55a86fde8717bd14d8020cd69efe5a85179ea008d653df0126d201ff30deda0de270264cf5c6dcd11ebfeb578dd547c3d5a26106befa3d";
  private static String privateexponent = "7ba9fbbda2641465c8e2c85ca24a2f137c1d6dbdd161f6dbc898f0fb2fbc734ff1ab5a7ebfe3e3b18bc1738ce125ffbd56b7941946c153d3dd1452bfab8a6e1b6335c1096d3adc2ea2e830908108386ec37db161299c333d7ac9051aa8095d8348019523e5d8dccac00f8db9447f7d3fc0be14560ea4843d00d34b09db0c64e1";
  /***
   * 公钥指数随意选，那么私钥就不能再随意选了，只能根据算法公式（ed%k=1，k=(p-1)(q-1)）进行运算出来。
   * 那么私钥指数会是多少位？根据ed关系，私钥d=(x*k+1)/e，所以单看这个公式，私钥指数似乎也不是唯一结果，
   * 可能大于也可能小于1024bits的，但我们习惯上也是指某个小于1024bits的大整数。
   * 包括前文的公钥指数，在实际运算和存储时为方便一般都是按照标准位长进行使用，前面不足部分补0填充，所以，
   * 使用保存和转换这些密钥需要注意统一缓冲区的长度
   */
  private static String privateModulus = "00aaddf90bdd1f2aedb8a16794757ad8ff7fc477d5da9b65c1e85d3a9d41b6dfa3f8e4bbf6a4b190cdc80ed96ef2d8ab84fa8b00ff6931d744b3514d7061cf009962dacd920ae927de9c55a86fde8717bd14d8020cd69efe5a85179ea008d653df0126d201ff30deda0de270264cf5c6dcd11ebfeb578dd547c3d5a26106befa3d";


  public static void main(String[] args) {

    System.out.println(privateModulus.length());
    String s = "27323920733164911451867488782308974860475197329376747415804156079709970187682448451781588982052297762345660617953852158966878724443762735012186340097169440943049125323096417197508432861481160605153913850703934445810629458395227158045391856956254962383009363583590935447886968943335901285404438069512056953888098271773940020987496723776003213355894021596514892977204275479138780813408604250886984523814726779952665635429849643982738113977529741259527972223530817580706135902382246527330022388052679839880693104503988813363227573050147428639177433072487587656723473337758912116832030995933595073262869216913930982372307";
    System.out.println(s.length());
    initKey();

    String source = "luoxiaohui";

    PublicKey publicKey = RSAUtil.getRSAPublicKey(publicModulus, publicexponent);
    String encript = RSAUtil.encryptString(publicKey, source);
    System.out.println("加密后数据：" + encript);

    PrivateKey privateKey = RSAUtil.getRSAPrivateKey(privateModulus, privateexponent);
    String newSource = RSAUtil.decryptString(privateKey, encript);

    System.out.println("解密后数据:" + newSource);
  }


  public static Map<String, Object> initKey() {
    KeyPairGenerator kpGenerator = null;
    try {
      kpGenerator = KeyPairGenerator.getInstance("RSA");
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    }
    kpGenerator.initialize(2048);
    KeyPair keyPair = kpGenerator.generateKeyPair();
    // 存储公钥
    PublicKey publicKey = keyPair.getPublic();
    // 存储密钥
    PrivateKey privateKey = keyPair.getPrivate();
    Map<String, Object> keyMap = new HashMap<String, Object>();
    keyMap.put("RSAPublicKey", publicKey);
    keyMap.put("RSAPrivateKey", privateKey);

    return keyMap;
  }
}









